/******************************************************************************
*@file     ec_bsp_key.c
*@brief    【描述】
*@author   zhjh
*@version  1.0
*@date     2023年12月19日
*
*@copyright  Copyright (c) 2023 天津柯迪斯科极有限公司 All rights reserved.
*
*@par 修改日志:
*<table>
*<tr><th>Date       <th>Version   <th>Author      <th>Description
*<tr><td>2023年12月19日<td>【版本号】     <td>【作者】     <td>【日志】
*</table>
    按键的触发逻辑：
        1、按键释放触发
        2、按键长按触发
        3、组合键长按触发

使用K3-S按键的使用逻辑：
        1.长按电源键：按下电源键2S及2S以上，仪表正常开机。
        2.短按UP键：加档位或参数的调节
        3.短按DOWN键：减档位或参数的调节
        4.短按电源键：切换功能界面显示
        5.长按UP键:开/关大灯
        6.长按DOWN键:按键6公里助推
        7.组合按键：
            ①同时长按UP和DOWN键：进入设置
            ②同时长按电源键和DOWN键：解绑蓝牙(诺有蓝牙要求)
            ③同时长按电源键和UP键：2秒以上视为恢复出厂设置
            4判断按键，如果加键减键同时按2秒以上开机，则进OTA升级，即关机状态，按住这两个键上电开机，则进行OTA升级


******************************************************************************/
#include "ec_bsp_key.h"
#include "flexible_button.h"
#define EC_BSP_DEBUG
__weak void ec_bsp_key_send(uint16_t key_value)
{
    printf("KEY_VALIE:%x\n",key_value);
}
static char *enum_event_string[] = {
    ENUM_TO_STR(FLEX_BTN_PRESS_DOWN),               //按下事件
    ENUM_TO_STR(FLEX_BTN_PRESS_CLICK),              //单击事件
    ENUM_TO_STR(FLEX_BTN_PRESS_DOUBLE_CLICK),       //双击事件
    ENUM_TO_STR(FLEX_BTN_PRESS_REPEAT_CLICK),       //连击事件
    ENUM_TO_STR(FLEX_BTN_PRESS_SHORT_START),        //短按开始事件
    ENUM_TO_STR(FLEX_BTN_PRESS_SHORT_UP),           //短按抬起事件
    ENUM_TO_STR(FLEX_BTN_PRESS_LONG_START),         //长按开始事件
    ENUM_TO_STR(FLEX_BTN_PRESS_LONG_UP),            //长按抬起事件
    ENUM_TO_STR(FLEX_BTN_PRESS_LONG_HOLD),          //长按保持事件
    ENUM_TO_STR(FLEX_BTN_PRESS_LONG_HOLD_UP),       //长按保持抬起事件
    ENUM_TO_STR(FLEX_BTN_PRESS_MAX),
    ENUM_TO_STR(FLEX_BTN_PRESS_NONE),
};

static char *enum_btn_id_string[] = {
    ENUM_TO_STR(EC_UP_KEY),
    ENUM_TO_STR(EC_DOWN_KEY),
    ENUM_TO_STR(EC_POWER_KEY),
    ENUM_TO_STR(EC_MODE_KEY),
    ENUM_TO_STR(EC_LIGHT_KEY),
    ENUM_TO_STR(EC_BUTTON_5),
    ENUM_TO_STR(EC_BUTTON_6),
};

static flex_button_t user_button[EC_BUTTON_MAX] = {0};//都初始化为0



/****************************K5按键************************************/
uint8_t key_scan_value[2];
void ec_bsp_key_read_gpio(void)
{
    gpio_set_level(GPIO_KEY_4, 1);
    vTaskDelay(2);
    key_scan_value[0] = gpio_get_level(GPIO_KEY_1);
    key_scan_value[1] = gpio_get_level(GPIO_KEY_2);
    gpio_set_level(GPIO_KEY_4, 0);
    vTaskDelay(2);
    gpio_set_level(GPIO_KEY_4, 1);
}
/****************************K5按键************************************/
static uint8_t common_btn_read(void *arg)
{
    uint8_t value = 0;
    flex_button_t *btn = (flex_button_t *)arg;
    switch (btn->id)
    {
        case EC_UP_KEY://上键
            value = gpio_get_level(GPIO_KEY_1);
            value = key_scan_value[0] | value;
            break;
        case EC_DOWN_KEY:
            value = gpio_get_level(GPIO_KEY_2);
            value = key_scan_value[1] | value;
            break;
        case EC_POWER_KEY:
            value = gpio_get_level(GPIO_KEY_3);
            break;
        case EC_MODE_KEY:
            value = gpio_get_level(GPIO_KEY_1);
            if((key_scan_value[0]==1)&&(value ==0));
            else value = 1;
            break;
        case EC_LIGHT_KEY:
            value = gpio_get_level(GPIO_KEY_2);
            if((key_scan_value[1]==1)&&(value ==0));
            else value = 1;
            break;
        default://目前其他的按键没有定义，返回1
            value = 1;
            break;
    }
    return value;
}

static void common_btn_evt_cb(void *arg)
{
    flex_button_t *btn = (flex_button_t *)arg;
    uint8_t i;
    uint16_t key_value = 0;
    switch (btn->event)
    {
        case FLEX_BTN_PRESS_SHORT_UP://短按释放
            for (i = 0; i < EC_BUTTON_MAX; i++)
            {
                if(btn->id == i)continue;//跳过自己的判断
                if(flex_button_event_read(&user_button[i]) == FLEX_BTN_PRESS_LONG_START || \
                    flex_button_event_read(&user_button[i]) == FLEX_BTN_PRESS_LONG_HOLD)//可做按键黏连判断，默认不用
                {
#ifdef ec_BSP_DEBUG
                    printf("[%s]:LONG HOLD\n", enum_btn_id_string[i]);
#endif
                    return;//找到第一个黏连按键
                }
            }
            //目前只处理，其他按键没有长按和长按保持，则返回此按键的时间，其他按键在其他状态不做处理。
#ifdef ec_BSP_DEBUG
            printf("[%s]:[%30s]\n", enum_btn_id_string[btn->id],enum_event_string[btn->event]);
#endif
            key_value |= (1 << btn->id);
            key_value |= ((uint16_t)btn->event<<8);
            ec_bsp_key_send(key_value);
            btn->event = FLEX_BTN_PRESS_NONE;//取消按键事件标记
            break;
        case FLEX_BTN_PRESS_LONG_START://判定为长按
            //查找其他按键是否有长按发生
            for (i = 0; i < EC_BUTTON_MAX; i++)
            {
                if(btn->id == i)continue;//跳过自己的判断
                if(flex_button_event_read(&user_button[i]) == FLEX_BTN_PRESS_LONG_START || \
                    flex_button_event_read(&user_button[i]) == FLEX_BTN_PRESS_LONG_HOLD)//
                {
#ifdef ec_BSP_DEBUG
                    printf("[%s] AND [%s]:LONG HOLD\n",enum_btn_id_string[btn->id],enum_btn_id_string[i]);
#endif
                        key_value |= (1 << btn->id);
                        key_value |= (1 << i);
                        key_value |= ((uint16_t)btn->event<<8);
                        ec_bsp_key_send(key_value);
                    return;//找到第一个黏连按键
                }
            }
            //走到这里说明，没有其他按键长按，有可能正在触发长按的路上
            for (i = 0; i < EC_BUTTON_MAX; i++)
            {
                if(btn->id == i)continue;//跳过自己的判断
                if(flex_button_event_read(&user_button[i]) == FLEX_BTN_PRESS_SHORT_START)//已经有按键按下，等待是否也是长按，触发组合键
                {
#ifdef ec_BSP_DEBUG
                    printf("[%s]waiting[%s]:LONG HOLD\n",enum_btn_id_string[btn->id],enum_btn_id_string[i]);
#endif
                    return;//其他按键有操作
                }
            }
            //走到这里说明其他按键没有任何操作,单个长按
#ifdef ec_BSP_DEBUG
            printf("[%s]:[%30s]\n", enum_btn_id_string[btn->id],enum_event_string[btn->event]);  
#endif
                key_value |= (1 << btn->id);
                key_value |= ((uint16_t)btn->event<<8);
                ec_bsp_key_send(key_value);
            break;
        case FLEX_BTN_PRESS_LONG_HOLD://长按保持5秒
#ifdef ec_BSP_DEBUG
            printf("[%s]:[%30s]\n", enum_btn_id_string[btn->id],enum_event_string[btn->event]);  
#endif
                key_value |= (1 << btn->id);
                key_value |= ((uint16_t)btn->event<<8);
                ec_bsp_key_send(key_value);
            break;
        case FLEX_BTN_PRESS_LONG_UP:    
        case FLEX_BTN_PRESS_LONG_HOLD_UP://长按释放，需要处理，组合键得释放。
#ifdef ec_BSP_DEBUG
            printf("[%s]:[%30s]\n", enum_btn_id_string[btn->id],enum_event_string[btn->event]);  
#endif
                key_value |= (1 << btn->id);
                key_value |= ((uint16_t)btn->event<<8);
                ec_bsp_key_send(key_value);
            btn->event = FLEX_BTN_PRESS_NONE;//取消按键事件标记
            break;
        default:
            break;
    }
}
void ec_bsp_key_init(void)
{
	gpio_config_t  GPIO_Initstructure;
	
	GPIO_Initstructure.mode 			    = GPIO_MODE_INPUT;
	GPIO_Initstructure.pull_down_en		    = GPIO_PULLDOWN_DISABLE;
	GPIO_Initstructure.pull_up_en			= GPIO_PULLUP_DISABLE;
	GPIO_Initstructure.intr_type	        = GPIO_INTR_DISABLE;
	GPIO_Initstructure.pin_bit_mask  		= (1ULL << GPIO_KEY_1) | (1ULL << GPIO_KEY_2) | (1ULL << GPIO_KEY_3);	/*Up、Down、Power按键，都是单按键，直接初始化为输入*/
	gpio_config(&GPIO_Initstructure);
	// GPIO_Initstructure.mode 			        = GPIO_MODE_INPUT_OUTPUT;
	// GPIO_Initstructure.pull_down_en		    = GPIO_PULLDOWN_DISABLE;
	// GPIO_Initstructure.pull_up_en			= GPIO_PULLUP_ENABLE;
	// GPIO_Initstructure.intr_type	            = GPIO_INTR_DISABLE;
	// GPIO_Initstructure.pin_bit_mask  		= (1ULL << GPIO_KEY_4); 
	// gpio_config(&GPIO_Initstructure);
    for (uint8_t i = 0; i < EC_BUTTON_MAX; i ++)
    {
        user_button[i].id = i;
        user_button[i].usr_button_read = common_btn_read;
        user_button[i].cb = common_btn_evt_cb;
        user_button[i].pressed_logic_level = 0;//设置按键按下时的逻辑电平
        user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(KEY_WOBBLE_PERIOD);//短按周期：40ms
        user_button[i].long_press_start_tick = FLEX_MS_TO_SCAN_CNT(KEY_LONG_PERIOD);//长按周期：1S
        if(i == EC_DOWN_KEY)
        {
            user_button[i].long_hold_start_tick = FLEX_MS_TO_SCAN_CNT(KEY_LONG_PERIOD*5);//长按保持：5S,用于识别上键Trip清零
        }
        user_button[i].long_hold_start_tick = FLEX_MS_TO_SCAN_CNT(KEY_LONG_PERIOD*3);//长按保持：3S
        user_button[i].max_multiple_clicks_interval = FLEX_MS_TO_SCAN_CNT(KEY_CONTINUE_PERIOD);///* 多次点击间隔s */
        flex_button_register(&user_button[i]);
    }
}





